package com.example.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.example.common.Result;
import com.example.common.ResultCode;
import com.example.entity.Account;
import com.example.entity.AuthorityInfo;
import com.example.exception.CustomException;
import com.example.entity.AdminInfo;
import com.example.entity.UserInfo;

import com.example.service.AdminInfoService;
import com.example.service.UserInfoService;

import com.example.service.VaptchaService;
import com.example.vo.VaptchaVo;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import cn.hutool.json.JSONUtil;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;

import java.util.*;
import java.util.stream.Collectors;

@RestController
public class AccountController {

@Value("${authority.info}")
private String authorityStr;

@Value("${vaptcha.vid}")
private String vaptchaVid;

@Value("${vaptcha.key}")
private String vaptchaKey;

@Resource
private AdminInfoService adminInfoService;

@Resource
private UserInfoService userInfoService;

@Resource
private VaptchaService vaptchaService;

/**
* 用户登录
*
* @param account  用户账户信息
* @param request  HTTP请求对象
* @return         返回包含登录成功后的用户信息的结果对象
*/
@PostMapping("/login")
public Result<Account> login(@RequestBody Account account, HttpServletRequest request) {
    // 检查请求参数是否完整
    if (StrUtil.isBlank(account.getName()) || StrUtil.isBlank(account.getPassword()) || account.getLevel() == null) {
    throw new CustomException(ResultCode.PARAM_LOST_ERROR);
    }

    Integer level = account.getLevel();
    Account login = new Account();
    if (1 == level) {
    // 管理员登录
    login = adminInfoService.login(account.getName(), account.getPassword());
    }
    if (2 == level) {
    // 用户登录
    login = userInfoService.login(account.getName(), account.getPassword());
    }

    // 将登录信息保存到会话中
    request.getSession().setAttribute("user", login);
    return Result.success(login);
    }

    /**
    * 用户注册
    *
    * @param account  用户账户信息
    * @return         返回包含注册成功后的用户信息的结果对象
    */
    @PostMapping("/register")
    public Result<Account> register(@RequestBody Account account) {
        Integer level = account.getLevel();
        Account login = new Account();
        if (1 == level) {
        // 管理员注册
        AdminInfo info = new AdminInfo();
        BeanUtils.copyProperties(account, info);
        login = adminInfoService.add(info);
        }
        if (2 == level) {
        // 用户注册
        UserInfo info = new UserInfo();
        BeanUtils.copyProperties(account, info);
        login = userInfoService.add(info);
        }

        return Result.success(login);
        }

        /**
        * 用户注销
        *
        * @param request  HTTP请求对象
        * @return         返回注销结果的结果对象
        */
        @GetMapping("/logout")
        public Result logout(HttpServletRequest request) {
        // 清空会话中的用户信息
        request.getSession().setAttribute("user", null);
        return Result.success();
        }

        /**
        * 获取用户认证信息
        *
        * @param request  HTTP请求对象
        * @return         返回用户认证信息的结果对象
        */
        @GetMapping("/auth")
        public Result getAuth(HttpServletRequest request) {
        // 从会话中获取用户信息
        Object user = request.getSession().getAttribute("user");
        if (user == null) {
        return Result.error("401", "未登录");
        }
        return Result.success(user);
        }

        /**
        * 获取用户账户信息
        *
        * @param request  HTTP请求对象
        * @return         返回用户账户信息的结果对象
        */
        @GetMapping("/getAccountInfo")
        public Result<Object> getAccountInfo(HttpServletRequest request) {
            // 从会话中获取用户信息
            Account account = (Account)request.getSession().getAttribute("user");
            if (account == null) {
            return Result.success(new Object());
            }
            Integer level = account.getLevel();
            if (1 == level) {
            // 查询管理员账户信息
            return Result.success(adminInfoService.findById(account.getId()));
            }
            if (2 == level) {
            // 查询用户账户信息
            return Result.success(userInfoService.findById(account.getId()));
            }

            return Result.success(new Object());
            }

            /**
            * 获取用户会话信息
            *
            * @param request  HTTP请求对象
            * @return         返回用户会话信息的结果对象
            */
            @GetMapping("/getSession")
            public Result<Map<String, String>> getSession(HttpServletRequest request) {
            // 从会话中获取用户信息
            Account account = (Account)request.getSession().getAttribute("user");
            if (account == null) {
            return Result.success(new HashMap<>(1));
            }
            Map<String, String> map = new HashMap<>(1);
            map.put("username", account.getName());
            return Result.success(map);
            }

            /**
            * 获取权限信息
            *
            * @return  返回权限信息的结果对象
            */
            @GetMapping("/getAuthority")
            public Result<List<AuthorityInfo>> getAuthorityInfo() {
                // 将权限信息字符串解析为权限信息列表
                List<AuthorityInfo> authorityInfoList = JSONUtil.toList(JSONUtil.parseArray(authorityStr), AuthorityInfo.class);
                    return Result.success(authorityInfoList);
                    }

                    /**
                    * 获取当前用户所能看到的模块信息
                    *
                    * @param request  HTTP请求对象
                    * @return         返回当前用户所能看到的模块信息的结果对象
                    */
                    @GetMapping("/authority")
                    public Result<List<Integer>> getAuthorityInfo(HttpServletRequest request) {
                        // 从会话中获取用户信息
                        Account user = (Account)request.getSession().getAttribute("user");
                        if (user == null) {
                        return Result.success(new ArrayList<>());
                        }

                        // 解析权限信息字符串
                        JSONArray objects = JSONUtil.parseArray(authorityStr);
                        for (Object object : objects) {
                        JSONObject jsonObject = (JSONObject)object;
                        if (user.getLevel().equals(jsonObject.getInt("level"))) {
                        JSONArray array = JSONUtil.parseArray(jsonObject.getStr("models"));
                        // 提取模块ID列表
                        List<Integer> modelIdList = array.stream().map((o -> {
                            JSONObject obj = (JSONObject)o;
                            return obj.getInt("modelId");
                            })).collect(Collectors.toList());
                            return Result.success(modelIdList);
                            }
                            }
                            return Result.success(new ArrayList<>());
                            }

                            /**
                            * 获取指定模块的权限信息
                            *
                            * @param modelId  模块ID
                            * @param request  HTTP请求对象
                            * @return         返回指定模块的权限信息的结果对象
                            */
                            @GetMapping("/permission/{modelId}")
                            public Result<List<Integer>> getPermission(@PathVariable Integer modelId, HttpServletRequest request) {
                                // 将权限信息字符串解析为权限信息列表
                                List<AuthorityInfo> authorityInfoList = JSONUtil.toList(JSONUtil.parseArray(authorityStr), AuthorityInfo.class);
                                    // 从会话中获取用户信息
                                    Account user = (Account)request.getSession().getAttribute("user");
                                    if (user == null) {
                                    return Result.success(new ArrayList<>());
                                    }
                                    Optional<AuthorityInfo> optional = authorityInfoList.stream().filter(x->x.getLevel().equals(user.getLevel())).findFirst();
                                        if (optional.isPresent()) {
                                        Optional<AuthorityInfo.Model> firstOption = optional.get().getModels().stream().filter(x->x.getModelId().equals(modelId)).findFirst();
                                            if (firstOption.isPresent()) {
                                            // 提取权限信息
                                            List<Integer> info = firstOption.get().getOperation();
                                                return Result.success(info);
                                                }
                                                }
                                                return Result.success(new ArrayList<>());
                                                }

                                                /**
                                                * 更新用户密码
                                                *
                                                * @param info     包含旧密码、新密码等信息的用户账户对象
                                                * @param request  HTTP请求对象
                                                * @return         返回更新密码结果的结果对象
                                                */
                                                @PutMapping("/updatePassword")
                                                public Result updatePassword(@RequestBody Account info, HttpServletRequest request) {
                                                // 从会话中获取用户信息
                                                Account account = (Account)request.getSession().getAttribute("user");
                                                if (account == null) {
                                                return Result.error(ResultCode.USER_NOT_EXIST_ERROR.code, ResultCode.USER_NOT_EXIST_ERROR.msg);
                                                }
                                                // 检查旧密码是否正确
                                                String oldPassword = SecureUtil.md5(info.getPassword());
                                                if (!oldPassword.equals(account.getPassword())) {
                                                return Result.error(ResultCode.PARAM_PASSWORD_ERROR.code, ResultCode.PARAM_PASSWORD_ERROR.msg);
                                                }
                                                // 更新密码
                                                info.setPassword(SecureUtil.md5(info.getNewPassword()));
                                                Integer level = account.getLevel();
                                                if (1 == level) {
                                                // 更新管理员密码
                                                AdminInfo adminInfo = new AdminInfo();
                                                BeanUtils.copyProperties(info, adminInfo);
                                                adminInfoService.update(adminInfo);
                                                }
                                                if (2 == level) {
                                                // 更新用户密码
                                                UserInfo userInfo = new UserInfo();
                                                BeanUtils.copyProperties(info, userInfo);
                                                userInfoService.update(userInfo);
                                                }

                                                info.setLevel(level);
                                                info.setName(account.getName());
                                                // 清空session，让用户重新登录
                                                request.getSession().setAttribute("user", null);
                                                return Result.success();
                                                }

                                                /**
                                                * 重置用户密码
                                                *
                                                * @param account  用户账户信息
                                                * @return         返回重置密码结果的结果对象
                                                */
                                                @PostMapping("/resetPassword")
                                                public Result resetPassword(@RequestBody Account account) {
                                                Integer level = account.getLevel();
                                                if (1 == level) {
                                                // 重置管理员密码
                                                AdminInfo info = adminInfoService.findByUserName(account.getName());
                                                if (info == null) {
                                                return Result.error(ResultCode.USER_NOT_EXIST_ERROR.code, ResultCode.USER_NOT_EXIST_ERROR.msg);
                                                }
                                                info.setPassword(SecureUtil.md5("123456"));
                                                adminInfoService.update(info);
                                                }
                                                if (2 == level) {
                                                // 重置用户密码
                                                UserInfo info = userInfoService.findByUserName(account.getName());
                                                if (info == null) {
                                                return Result.error(ResultCode.USER_NOT_EXIST_ERROR.code, ResultCode.USER_NOT_EXIST_ERROR.msg);
                                                }
                                                info.setPassword(SecureUtil.md5("123456"));
                                                userInfoService.update(info);
                                                }

                                                return Result.success();
                                                }

                                                /**
                                                * 验证Vaptcha验证码
                                                *
                                                * @param vaptchaVo  包含Vaptcha验证信息的对象
                                                * @param request    HTTP请求对象
                                                * @return           返回验证结果的结果对象
                                                */
                                                @PostMapping("/veriy")
                                                public Result veriy(@RequestBody VaptchaVo vaptchaVo, HttpServletRequest request) {
                                                vaptchaVo.setIp(request.getHeader("x-forwarded-for"));
                                                // 验证Vaptcha验证码
                                                Boolean verify = vaptchaService.verify(vaptchaVo);
                                                if (verify) {
                                                return Result.success();
                                                }
                                                else {
                                                return Result.error(ResultCode.VERIFY_CODE_ERROR.code, ResultCode.VERIFY_CODE_ERROR.msg);
                                                }
                                                }
                                                }
